import React from 'react';
import PropTypes from 'prop-types';
import memorize from 'lodash-decorators/memoize';
import ReactPlugin from '../plugin';
import Value from '../model/value';
import Controller from '../controller';
import { isFunction } from '../utils/is-object';

class Editor extends React.PureComponent {
  static defaultProps = {
    plugins: [],
    // value: Value.create({}),
  };

  static propTypes = {
    // value: PropTypes.instanceOf(Value),
    plugins: PropTypes.array,
  };

  state = {
    value: Value.create({}),
  };
  
  mounted = false;

  // static getDerivedStateFromProps(props, state){    
  // const { value } = state;
  // const styles = value.toJS().document.nodes.map(node => {
  //   const dom = document.getElementById(node.key);
  //   if(dom){
  //     const style = window.getComputedStyle(dom);
  //     return {
  //       w: style.width,
  //       h: style.height,
  //       l: style.left,
  //       r: style.right,
  //     };
  //   }
  //   return {};
  // });
  // console.log(styles);
  // }

  componentDidMount() {
    this.mounted = true;
  }

  get schema() {
    return this.controller.schema;
  }

  get value() {
    return this.controller.value;
  }

  get actionStack() {
    return this.controller.actionStack;
  }

  handleChange = ({ value, actions }) => {
    if (isFunction(this.props.onChange)) {
      this.props.onChange({ value, actions });
    }
  };

  apply(...args) {
    return this.controller.apply(...args);
  }

  command(...args) {
    return this.controller.command(...args);
  }

  query(...args) {
    return this.controller.query(...args);
  }

  registerCommand(...args) {
    return this.controller.registerCommand(...args);
  }

  registerQuery(...args) {
    return this.controller.registerQuery(...args);
  }

  run(...args) {
    return this.controller.run(...args);
  }

  @memorize
  makeController(plugins) {
    const onChange = ({ value, action }) => {
      if (this.mounted) {
        this.setState({
          value,
        });
      }
      this.handleChange({ value, action });
    };
    const controller = new Controller({
      plugins: ReactPlugin({ plugins }),
      onChange,
      controller: this,
      construct: false,
    });
    return controller;
  }

  applyAction(...args) {
    return this.controller.applyAction(...args);
  }

  render() {
    const { plugins, value: valueFromProps, mobileValue } = this.props;
    const { value: valueFromState } = this.state;
    let value = valueFromProps || valueFromState;
    if(mobileValue){
      value = value.set('document', value.document.set('nodes', mobileValue.document.nodes)); 
    }
    this.controller = this.makeController(plugins);
    this.run('onConstruct');
    this.controller.value = value;
    const content = this.controller.run('renderEditor', {
      ...this.props,
      value,
    });
    return content;
  }
}

export default Editor;
